/*
 * akiusb-host.h - Header file for host side functions
 *
 * Copyright (C) 2009 Free Software Initiative of Japan
 *
 * Written by Wiktor Langowski <jolkaczad@gmail.com>
 *
 * Distributed under GNU General Public License version 3 (or later)
 */

#include <stdio.h>
#include <string.h>
#include <usb.h>
#include <stdlib.h>
#include <unistd.h>

#include <poll.h>

#define USB_VENDOR  0x16c0
#define USB_PRODUCT 0x05dc
#define USB_MANUFACTURER_STR "fsij.org"
#define USB_PRODUCT_STR "Aki-USB"
#define USB_SERIALNUMBER_STR "0"

#define ENDPOINT     2

#define EEPROM_SAVE	1
#define EEPROM_NSAVE	0

#define EEPROM_SASIZE 7

/*
 * Control transfer stuff
 */
#define REQUESTTYPE USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN
#define CTRL_GET_SETTINGS 1

/* ---------- First layer device commands ---------- */
/*
 * Sends one column worth of bitmap data into vram. The function utilizes
 * the global device variable "vram_ptr".
 */
#define AKIUSB_DRAW 0
int send_one_column (usb_dev_handle *udev, unsigned char *bits);

/*
 * orders the ATmega to clear out all the contents of its vram immediately
 */
#define AKIUSB_CLRSCR 2
int send_cmd_clrscr (usb_dev_handle *udev);

/*
 * Sets the mode of display, concerning brightness.
 * if "mode" equals 0, than "value" sets the static brightness. "value"
 * must be in the range <0,12>, 0 being the dim, and 12 the brightest setting.
 *
 * Other modes of brightness modulation are set by passing "mode" as:
 * 1 - for sawtooth wave
 * 2 - for triangle wave (rising)
 * 3 - triangle wave (falling)
 * 4 - blinking with discreet values of brightness
 *
 * when assigning a non-zero value to "mode", "value" is ignored
 */
#define AKIUSB_VMODE 3
int send_cmd_vmode (usb_dev_handle *udev, \
			   unsigned char mode, unsigned char value);

/*
 * Renders a character at vram_ptr. "c" holds the number of the character
 * in the font compiled into the device side software at etl-font-r.c.inc
 */
#define AKIUSB_CHAR 4
int send_cmd_char (usb_dev_handle *udev, unsigned char c);

/*
 * Resets vram_disp_pos. "col" is the column number to which new data
 * or characters will be written. vram_disp_pos will be equal to col*2,
 * because every column consists of two vram entries.
 */
#define AKIUSB_SETDSP 5
int send_cmd_setdsp (usb_dev_handle *udev, unsigned char col);

/*
 * Sets the column number, to which data will be send for displaying.
 * col must be less than DISP_COLUMNS as defined in aki-usb.c
 */
#define AKIUSB_SETCOL 6
int send_cmd_setcol (usb_dev_handle *udev, unsigned char col);

/*
 * Uploads an array of characters or bitmap data to the device's EEPROM
 * for saving between resets. More specificaly, this function commands
 * the ATmega to write text to its (her?) own EEPROM by itself (herself?).
 *
 * The text[] contents are always copied to the beginning of EEPROM
 * space, no appending. Parameters are self explanatory: "text" is the pointer
 * to the source array, "len" is its length.
 *
 * To display the text just written, send_cmd_reset() must be called,
 * so ATmega knows to update its text[] with the new contents of EEPROM.
 */
#define AKIUSB_WEEPROM 7
int send_cmd_weeprom (usb_dev_handle *udev, const char *text, int len);

/*
 * Clears EEPROM area filling it with 0x00. Value of "a" determines which
 * logical segments are going to be erased:
 *  0: all
 *  1: the text/bitmap area (everything but EEP_SASIZE bytes at the end)
 *  2: settings area (last EEP_SASIZE bytes)
 */
#define AKIUSB_CEEPROM 8
int send_cmd_ceeprom (usb_dev_handle *udev, unsigned char a);

/*
 * Loads the text/bitmap segment of EEPROM into text[] area and the settings
 * segment into main memory. Often called after updating the EEPROM area 
 * with new data.
 */
#define AKIUSB_RESET 9
int send_cmd_reset (usb_dev_handle *udev);

/*
 * Sends a text/bitmap array to the device for keeping in RAM only.
 * All rules (maximum size, special characters etc.) concerning text[] 
 * in device RAM aplly.
 *
 * The contents of "text" are displayed immediately after sending.
 * XXX probably broken;
 */
#define AKIUSB_SET_ONETIME 11
int send_cmd_set_onetime (usb_dev_handle *udev, const char *text, int len);

/*
 * These send an array of settings to be saved in EEPROM or RAM. The meaning
 * of particular cells is as follows:
 *  eep_settings[0]: VMODE
 *    Described earlier at send_cmd_vmode ().
 *  eep_settings[1]: brightness
 *    Takes values <0, 12> 0 being the brightest setting. The scale is
 *    near linear.
 *  eep_settings[2]: scroll speed
 *    Value of 0 sets the speed to a default of INTERP_SCROLL_WAIT.
 *    Values <1, 255> affect scrolling speed in a linear fashion, 255 being
 *    the slowest.
 *  eep_settings[3]: blinking speed
 *    0 sets it to COUNT_MAX
 *    <1, 255> will determine the time between flashes. 255 is longest,
 *    scale is linear.
 *  eep_settings[4]: scroll direction; XXX not implemented yet.
 *  eep_settings[5-7] are not populated for the moment and will be ignored.
 *     
 * Default settings have values of 0x00 in the array so that they're
 * read as legit, when EEPROM is clear.
 */
#define AKIUSB_SETTINGS_EEPROM 12
int send_cmd_set_settings_eeprom (usb_dev_handle *udev, unsigned char *settings);
#define AKIUSB_SETTINGS_RAM 13
int send_cmd_set_settings_ram (usb_dev_handle *udev, unsigned char *settings);

/*
 * Stops the data interpreter on the device freezing the display state.
 */
#define AKIUSB_STOP 14
int send_cmd_stop (usb_dev_handle *udev);

/*
 * Unfreezes the display after the intepreter has been halted by
 * send_cmd_stop().
 */
#define AKIUSB_GO 15
int send_cmd_go (usb_dev_handle *udev);

/*
 * retrieves the current set of settings from the device's EEPROM
 */
#define AKIUSB_GET_EEPROM_SETT 1
int send_cmd_get_settings_eeprom (usb_dev_handle *udev, unsigned char *settings);

/*
 * retrieves a set of settings from device's RAM
 */
#define AKIUSB_GET_RAM_SETT 2
int send_cmd_get_settings_ram (usb_dev_handle *udev, unsigned char *settings);

/* ---------- Second layer device commands ---------- */
/*
 * Sets a new array of settings on the device with the option of saving it
 * to EEPROM for keeping between runs. In both cases the changes are
 * visible right away.
 * The 'destination' can be set to EEPROM_SAVE or EEPROM_NSAVE, for saving on
 * EEPROM and keeping in RAM only, respectively.
 */
int set_settings (usb_dev_handle *udev, unsigned char *settings, \
		int destination);

/*
 * Copies an array of settings from the device to *settings. The source can
 * be either RAM or EEPROM indicated by passing the variable 'destination' as
 * EEPROM_SAVE or EEPROM_NSAVE.
 */
int get_settings (usb_dev_handle *udev, unsigned char *settings, \
		int destination);

/* ---------- Other ---------- */
/*
 * Buffer for data to be send in one packet via USB 
 */
#define USBLOWSPEED_BUFSIZE 8
char usbbuf[USBLOWSPEED_BUFSIZE];

/*
 * The structure is helpful for keeping information about the currently
 * processed text array.
 */
struct context {
  int char_col;	  /* which column in a character is being processed */ 
  int text_index; /* index inside text[] */
  char *text;	  /* pointer to the displayed text array */
};

/*
 * checks if the connected USB device name matches our device's name
 */
int compare_usb_string (usb_dev_handle *udev, int index, char *str);

/*
 * Fetches and returns the bits for a given context. Also, the function
 * iterates further along the columns so there is no need to increment
 * any element of the context structure.
 */ 
unsigned char *get_bits_for_one_column (struct context *ctx);

/*
 * This handles the entire process of reading and sending bytes needed
 * to display a given array of characters.
 *
 * The procedure does exactly what the device itself, or even less.
 * It should be expanded because only the host side could manage very large
 * character sets, like Japanese.
 */
#define TIMEOUT 50 /* in milliseconds */
#define BUFSIZE 256
int render_text_scrolling (usb_dev_handle *udev, char *text);

/*
 * This is called to set up the usb interface. For further information
 * please refer to the libusb documentation which would describe the process
 * in detail.
 *
 * The parameters passed are pointers to empty structures best defined
 * in main().
 */
int manage_usb (struct usb_bus **bus, struct usb_device **dev, \
		usb_dev_handle **udev);
/*
 * Returns the width of a given character.
 */
int char_width (unsigned char c);

/*
 * Returns a pointer to an array which containins bits for a given letter.
 */
unsigned char *char_bits (unsigned char c);
